﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace blackhouse.BlackApart.Data.Caching {
    public class CachedOpinionsDataAccess : IOpinionsDataAccess {

        #region Fields

        private IOpinionsDataAccess decoratedDataAccess;
        private NemoCache cache;

        #endregion

        #region Constructors

        public CachedOpinionsDataAccess(IOpinionsDataAccess decoratedDataAccess, string connectionStringToDecoretedDb) {
            this.decoratedDataAccess = decoratedDataAccess;
            this.cache = new NemoCache(TimeSpan.FromMinutes(2), connectionStringToDecoretedDb);
        }

        #endregion

        #region Methods

        public OpinionCategoryData[] GetOpinionsCategories(string language) {
            cache.Reset();
            cache.SetDependencyTables("T113");
            cache.SetKey("GetOpinionsCategories" + language);
            OpinionCategoryData[] data = cache.GetData<OpinionCategoryData[]>();
            if (data == null) {
                data = this.decoratedDataAccess.GetOpinionsCategories(language);
                cache.SetCaching(data);
            }
            return data;
        }

        public int SaveOpinion(int opinionId, string inPlusOpinion, string inMinusOpinion, DateTime publishedDate, string publisherCategory, string publisherFirstName, string publisherLastName, string publisherCountry, string language, int userId) {
            this.cache.TouchTimes();
            return this.decoratedDataAccess.SaveOpinion(opinionId, inPlusOpinion, inMinusOpinion, publishedDate, publisherCategory, publisherFirstName, publisherLastName, publisherCountry, language, userId);
        }

        public int SaveModerateOpinion(int opinionId, string inPlusOpinion, string inMinusOpinion, string answer, int userId) {
            this.cache.TouchTimes();
            return this.decoratedDataAccess.SaveModerateOpinion(opinionId, inPlusOpinion, inMinusOpinion, answer, userId);
        }

        public OpinionData GetOpinion(int opinionId) {
            cache.Reset();
            cache.SetDependencyTables("T117");
            cache.SetParameters(opinionId);
            cache.SetKey("GetOpinion");
            OpinionData data = cache.GetData<OpinionData>();
            if (data.Id == 0) {
                data = this.decoratedDataAccess.GetOpinion(opinionId);
                cache.SetCaching(data);
            }
            return data;
        }

        public void AddOpinionDetailValue(int opinionId, int categoryId, float val) {
            this.cache.TouchTimes();
            this.decoratedDataAccess.AddOpinionDetailValue(opinionId, categoryId, val);
        }

        public Dictionary<int, float> GetOpinionDetails(int opinionId) {
            cache.Reset();
            cache.SetDependencyTables("T117");
            cache.SetParameters(opinionId);
            cache.SetKey("GetOpinionDetails");
            Dictionary<int, float> data = cache.GetData<Dictionary<int, float>>();
            if (data == null) {
                data = this.decoratedDataAccess.GetOpinionDetails(opinionId);
                cache.SetCaching(data);
            }
            return data;
        }

        public bool AddOpinionToReservation(int opinionId, int reservationId) {
            this.cache.TouchTimes();
            return this.decoratedDataAccess.AddOpinionToReservation(opinionId, reservationId);
        }

        public StatisticOpinionData[] GetStatisticOpinionData() {
            cache.Reset();
            cache.SetDependencyTables("T51", "T117", "T117_T125", "T125", "T51_T43", "T43", "T19");
            cache.SetKey("GetStatisticOpinionData");
            StatisticOpinionData[] data = cache.GetData<StatisticOpinionData[]>();
            if (data == null) {
                data = this.decoratedDataAccess.GetStatisticOpinionData();
                cache.SetCaching(data);
            }
            return data;
        }

        public OpinionData[] GetOpinionsHeader(bool includeNonPublic) {
            cache.Reset();
            cache.SetDependencyTables("T51", "T117", "T117_T125", "T125", "T51_T43", "T43", "T19");
            cache.SetKey("GetOpinionsHeader");
            cache.SetParameters(includeNonPublic);
            OpinionData[] data = cache.GetData<OpinionData[]>();
            if (data == null) {
                data = this.decoratedDataAccess.GetOpinionsHeader(includeNonPublic);
                cache.SetCaching(data);
            }
            return data;
        }

        public OpinionCategoryValueData[] GetOpinionsDetails(bool includeNonPublic) {
            cache.Reset();
            cache.SetDependencyTables("T51", "T117", "T117_T125", "T125", "T51_T43", "T43", "T19");
            cache.SetKey("GetOpinionsDetails");
            cache.SetParameters(includeNonPublic);
            OpinionCategoryValueData[] data = cache.GetData<OpinionCategoryValueData[]>();
            if (data == null) {
                data = this.decoratedDataAccess.GetOpinionsDetails(includeNonPublic);
                cache.SetCaching(data);
            }
            return data;
        }

        public OpinionTextData[] GetOpinionTextValues(string language) {
            cache.Reset();
            cache.SetDependencyTables("T251");
            cache.SetKey("GetOpinionTextValues");
            cache.SetParameters(language);
            OpinionTextData[] data = cache.GetData<OpinionTextData[]>();
            if (data == null) {
                data = this.decoratedDataAccess.GetOpinionTextValues(language);
                cache.SetCaching(data);
            }
            return data;
        }

        public void PublishOpinion(int opinionId, int userId) {
            this.cache.TouchTimes();
            this.decoratedDataAccess.PublishOpinion(opinionId, userId);
        }

        public int FindReservationToAddOpinion(int apartmentTypeId) {
            return this.decoratedDataAccess.FindReservationToAddOpinion(apartmentTypeId);
        }

        #endregion

    }
}
